import unittest
import time


from license.services import _renewal_certificate, _generate_certificate, generate_ts, download_ts, \
    cert_renewal
from license.utils.theseus_tool import TheseusTool
from license import constants as c
from license.models.device import *
from license.models.license import *

from django.test import TestCase

# 单元测试

# 基本测试

# 查询：machina_code查经销商
# 查询：machina_code查店铺
# 查询：machina_code查账号
# 查询：machina_code查序列号

# 激活：错误的激活码
# 激活-设备边界条件：激活的时候设备不存在
# 激活-序列号边界条件：序列号已经使用
# 激活-序列号边界条件：序列号不存在
# 激活-序列号边界条件：序列号对应的经销商状态为禁用
# 激活-序列号边界条件：序列号激活次数超过上限3次
"""
预期；A设备激活过1次，然后A设备损坏（或者是更换了配件，导致生成的machine_code发生了变化）变成了B设备，B设备激活，A设备无法使用
"""


# 激活-7天：用7天的来激活
# 激活-30天：用30天的来激活
# 激活-永久：用永久的证书
# 激活边界条件：还在正常状态下，但是又进行了激活，时间增加
# 激活-续期：比如原有的服务时间还剩下7天，那么使用新的序列号，，时间增例如30天进行激活加30天，服务时间为37天
# 激活-续期边界条件：边界条件：如果原有的服务时间是永久的，那么使用新的序列号，例如30天进行激活，提示激活失败；已经是永久的，那么不能进行激活，避免客户投诉
# 激活-更换经销商：原客户经销商是A，使用经销商B的序列号进行激活以后，客户的经销商变更成了B


# TS文件：生成TS文件生成测试，包括性能
# TS文件：生成TS文件并异步上传

# 证书类：证书加密，数据加密并创建证书，更新到数据库
# 证书类：证书解密，数据库中找到任意一个证书，并解密


# 数据库：读取经销商
# 数据库：读取设备
# 数据库：读取账户
# 数据库：读取门店


# SIGN 测试通过
class TestRenewalCertificate(unittest.TestCase):

    def test_renewal_certificate_success(self):
        machine_code = "qhFjPdGYNM66hY8-DRuy7wLTMCaABAPxgaAwedzlMeo~"
        cert_valid_time = "1000"
        cert_data = "4AkUl8qCVWjMMMZmPDtHzho29F0j3XSG13Jmwbs3u8de3PshGqGPTj4K92b79f-Hl_0~.gxoINylK0fN9jr-GcOOqwQ~~"
        # TODO 证书续期
        # self.assertEqual(result_code, c.SUCCESS)
        # self.assertTrue(success)
        # self.assertIsNotNone(new_cert_data)

    def test_renewal_certificate_failure(self):
        # 模拟抛出异常的情况
        def mock_renewal_cert(*args, **kwargs):
            raise Exception("Test exception")

        original_fun = TheseusTool.renewal_cert
        TheseusTool.renewal_cert = mock_renewal_cert
        machine_code = "qhFjPdGYNM66hY8-DRuy7wLTMCaABAPxgaAwedzlMeo~"
        cert_valid_time = "2025-09-25"
        cert_data = "4AkUl8qCVWjMMMZmPDtHzho29F0j3XSG13Jmwbs3u8de3PshGqGPTj4K92b79f-Hl_0~.gxoINylK0fN9jr-GcOOqwQ~~"
        # TODO 证书续期
        # TheseusTool.renewal_cert = original_fun
        # self.assertEqual(result_code, c.ERROR_CERT_RENEWAL_FAIL)
        # self.assertFalse(success)
        # self.assertIsNone(new_cert_data)


# SIGN 测试通过
class TestGenerateCertificate(unittest.TestCase):

    def test_generate_certificate_success(self):
        machine_code = "qhFjPdGYNM66hY8-DRuy7wLTMCaABAPxgaAwedzlMeo~"
        cert_valid_time = "1000"
        cert_encrypt_key = None
        result_code, success, cert_data, cert = _generate_certificate(machine_code, cert_valid_time, cert_encrypt_key)
        self.assertEqual(result_code, c.SUCCESS)
        self.assertTrue(success)
        self.assertIsNotNone(cert_data)
        self.assertIsNotNone(cert)

    def test_generate_certificate_failure(self):
        # 模拟抛出异常的情况
        def mock_encode_cert(*args, **kwargs):
            raise Exception("Test exception")

        original_encode_cert = TheseusTool.encode_cert
        TheseusTool.encode_cert = mock_encode_cert

        machine_code = "test_machine_code"
        cert_valid_time = "2025-09-25"
        cert_encrypt_key = "test_encrypt_key"
        result_code, success, cert_data, cert = _generate_certificate(machine_code, cert_valid_time, cert_encrypt_key)
        self.assertEqual(result_code, c.ERROR_CERT_GENERATE_FAIL)
        self.assertFalse(success)
        self.assertIsNone(cert_data)
        self.assertIsNone(cert)

        # 恢复原始函数
        TheseusTool.encode_cert = original_encode_cert


# SIGN 测试通过
class TestGenerateTs(unittest.TestCase):

    def test_generate_ts_success(self):
        machine_code = "qhFjPdGYNM66hY8-DRuy7wLTMCaABAPxgaAwedzlMeo~"
        result, success = generate_ts(machine_code)
        self.assertEqual(result, "ts文件生成成功")
        self.assertTrue(success)

    def test_generate_ts_device_not_found(self):
        machine_code = "non_existent_machine_code"
        result, success = generate_ts(machine_code)
        self.assertEqual(result, c.ERROR_MACHINE_CODE_INVALID)
        self.assertFalse(success)

    def test_generate_ts_serial_not_found(self):
        machine_code = "BhN6B93NuilsOVZTyjaHhD9r04dbp8NsGcrCGYRQvDU~"
        result, success = generate_ts(machine_code)
        self.assertEqual(result, c.ERROR_MACHINE_CODE_INVALID)
        self.assertFalse(success)


# SIGN 测试通过
class TestDownloadTs(unittest.TestCase):

    def test_download_ts_success(self):
        machine_code = "qhFjPdGYNM66hY8-DRuy7wLTMCaABAPxgaAwedzlMeo~"

        result_dict, success = download_ts(machine_code)
        self.assertTrue(success)

    def test_download_ts_device_not_found(self):
        machine_code = "non_existent_machine_code"
        result_dict, success = download_ts(machine_code)
        self.assertEqual(success, False)


# SIGN 测试通过
class TestTsStatus(TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_ts_status_success(self):
        machine_code = "qhFjPdGYNM66hY8-DRuy7wLTMCaABAPxgaAwedzlMeo~"
        result_dict, success = ts_status(machine_code)
        self.assertTrue(success)

    def test_ts_status_device_not_found(self):
        machine_code = "non_existent_machine_code"
        for i in range(1000):
            result_dict, success = ts_status(machine_code)
            self.assertEqual(success, False)


class TestCertRenewal(unittest.TestCase):

    def test_cert_renewal_success(self):
        raw_machine_info = "test_raw_machine_info"
        result_dict, success = cert_renewal(raw_machine_info, machine_code="test_machine_code")
        self.assertTrue(success)
        self.assertIn("token", result_dict)
        self.assertIn("payload", result_dict)
        self.assertIn("cert_data", result_dict)

    def test_cert_renewal_device_not_found(self):
        def mock_get_device(*args, **kwargs):
            raise Device.DoesNotExist

        Device.objects.get = mock_get_device

        raw_machine_info = "test_raw_machine_info"
        result_dict, success = cert_renewal(raw_machine_info, machine_code="non_existent_machine_code")
        self.assertEqual(result_dict, None)
        self.assertFalse(success)

    def test_cert_renewal_serial_not_found(self):
        def mock_get_serial(*args, **kwargs):
            raise Serial.DoesNotExist

        Serial.sharding_get().objects.get = mock_get_serial

        raw_machine_info = "test_raw_machine_info"
        result_dict, success = cert_renewal(raw_machine_info, machine_code="test_machine_code")
        self.assertEqual(result_dict, None)
        self.assertFalse(success)

    def test_cert_renewal_machine_info_invalid(self):
        raw_machine_info = "invalid_machine_info"
        result_dict, success = cert_renewal(raw_machine_info, machine_code="test_machine_code")
        self.assertEqual(result_dict, c.ERROR_MACHINE_INFO_INVALID)
        self.assertFalse(success)

    def test_cert_renewal_cert_expired(self):
        class MockCert:
            def __init__(self):
                self.expire_time = int(time.time()) - 100

        def mock_decode_cert(*args, **kwargs):
            return MockCert()

        self.original_decode_cert = TheseusTool.decode_cert
        TheseusTool.decode_cert = mock_decode_cert

        raw_machine_info = "test_raw_machine_info"
        result_dict, success = cert_renewal(raw_machine_info, machine_code="test_machine_code")
        self.assertEqual(result_dict, c.ERROR_CERT_EXPIRE)
        self.assertFalse(success)

        # 恢复原始方法
        TheseusTool.decode_cert = self.original_decode_cert


if __name__ == '__main__':
    unittest.main()
